type Char
    native;  // rune (int32)

type String
    native;  // string


export function = : &(Char,Char) => Bool  native '__CharEqual';

export function Char?:
    &(Number) => Maybe[Char]
    native '__CharFromInteger';


export function String:
    &(Char) => String
    native '__StringFromChar';

export function String:
    &(List[Char]) => String
    native '__StringFromListOfChar';

export method String.String: String
    &(s) => s;

export method String.length: Number
    native '__StringLength';

export method String.empty: Bool
    &(s) => (s = '');

export method String.Seq: Seq[Char]
    native '__StringToSeq';

export method String.List: List[Char]
    &(str) => str.{Seq}.{List};

export function = : &(String,String) => Bool  native '__StringEqual';
export function < : &(String,String) => Bool  native '__StringLessThan';
export function <> : &(String,String) => Ordering  native '__StringCompare';

/// encodes string into UTF-8 byte sequence
export function encode:
    &(String) => Bytes
    native '__EncodeUtf8';

/// decodes string from UTF-8 byte sequence
export function decode:
    &(Bytes) => Maybe[String]
    native '__DecodeUtf8';

/// decodes string from UTF-8 byte sequence (outputs \uFFFD on error)
export function decode*:
    &(Bytes) => String
    native '__DecodeUtf8Casual';

export function quote:
    &(String) => String
    native '__Quote';

export function unquote:
    &(String) => Maybe[String]
    native '__Unquote';

export function ??:
    &(String,String) => String
    &(s,fallback) => if s.empty: fallback, else: s;

export function shift:
    &(String) => Maybe[(Char,String)]
    native '__StringShift';

export function shift-prefix:
    &(String,String) => Maybe[String]
    native '__StringShiftPrefix';

export function contains:
    &(String,String) => Bool
    native '__StringContains';

export function contains:
    &(String,Char) => Bool
    &(s,char) =>
        ({ Seq s } some &(c) => (c = char));

export function concat:
    &(List[String]) => String
    native '__StringConcat';

export function split:
    &(String,String) => Seq[String]
    native '__StringSplit';

export function join:
    &(Seq[String],String) => String
    native '__StringJoin';

export function join:
    &(Seq[String],Char) => String
    &(seq,char) => seq.{join({String [char]})};

export function join:
    &(List[String],String) => String
    &(arr,sep) => arr.{Seq}.{join(sep)};

export function join:
    &(List[String],Char) => String
    &(arr,char) => arr.{Seq}.{join(char)};

export function trim:
    &(String,Char) => String
    native '__StringTrim';

export function trim-left:
    &(String,Char) => String
    native '__StringTrimLeft';

export function trim-right:
    &(String,Char) => String
    native '__StringTrimRight';

export function trim-prefix:
    &(String,String) => String
    native '__StringTrimPrefix';

export function trim-suffix:
    &(String,String) => String
    native '__StringTrimSuffix';

export function has-prefix:
    &(String,String) => Bool
    native '__StringHasPrefix';

export function has-suffix:
    &(String,String) => Bool
    native '__StringHasSuffix';


